package com.plian.system.service.hr.staff.check;

import com.plian.Tools.CacheUtil;
import com.plian.Tools.EncryptUtil;
import com.plian.Tools.StringUtil;
import com.plian.Tools.TokenUtil;
import com.plian.system.bean.staff.StaffFilesExcelBean;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.entity.hr.staff.StaffFiles;
import com.plian.system.excel.ImportExcelUtil;
import com.plian.system.excel.ImportResult;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.BaseConstant.BASE64_KEY;

@AllArgsConstructor
@Slf4j
public class StaffExcelCheckData {

	private final static String OBJECT_MSG = "未找到对应对象!";
	/**
	 * 人员档案导入 主表校验
	 * @param readExcels Excel导入的员工数据
	 * @param staffFilesList 现有的所有人员列表，用于查重校验
	 * @param progressId 流程key
	 * @param codeMap 员工档案中所有code转id的参照字典
	 * @param nameMap 员工档案中所有name转id的参照字典(指单位)
	 * @param deptUnitMap 员工档案中所有部门名称转id的参照字典(部门与单位存在关联依赖)
	 * @param isCover 是否为导入覆盖（true:覆盖，false:新增）
	 * @return ImportResult
	 */
	public static ImportResult checkStaffData(List<Object> readExcels, List<StaffFiles> staffFilesList, String progressId,
											  HashMap<String, List<String>> codeMap, HashMap<String, Map<String,String>> nameMap,
											  HashMap<String,Map<String,Long>> deptUnitMap, HashMap<String,Map<String,String>> deptUnitCodeMap,Boolean isCover) {
		ImportResult importResult = new ImportResult(true,"");
		List<Object> objectStaffFilesList= new ArrayList<>(staffFilesList);
		StringBuilder msg = new StringBuilder();

		List<String> codeList = new ArrayList<>();

		//数据判空及数据类型校验
		for (Object readExcel : readExcels) {
			StaffFilesExcelBean staffExcelBean =(StaffFilesExcelBean)readExcel;
			int index = readExcels.indexOf(readExcel);
			//编码判重队列
			codeList.add(staffExcelBean.getStaffCode());
			//判空
			msg.append(ImportExcelUtil.checkEmpty("2", "证件号", staffExcelBean.getStaffCode(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "姓名", staffExcelBean.getStaffName(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "证件类型", staffExcelBean.getDocumentTypeId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "性别", staffExcelBean.getGenderId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "出生日期", staffExcelBean.getBirthday(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "民族", staffExcelBean.getNationId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "政治面貌", staffExcelBean.getPoliticCountenanceId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "健康状况", staffExcelBean.getHealthConditionId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "单位名称", staffExcelBean.getCompanyNameId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "最高学历", staffExcelBean.getEducationalId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "参加工作时间", staffExcelBean.getWorkTime(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "本单位入职时间", staffExcelBean.getCompanyInitiationTime(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "部门名称", staffExcelBean.getDepartmentNameId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "管理类别", staffExcelBean.getManagementCategoryId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "职务名称", staffExcelBean.getJobNameId(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "籍贯", staffExcelBean.getNativePlace(), index).getMsg());
//			msg.append(ImportExcelUtil.checkEmpty("2", "入党/团时间", staffExcelBean.getJoinPartyTime(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "联系电话", staffExcelBean.getTelephone(), index).getMsg());
			msg.append(ImportExcelUtil.checkEmpty("2", "任现职时间", staffExcelBean.getTenureTime(), index).getMsg());
			//判断数据类型
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "证件类型",
				staffExcelBean.getDocumentTypeId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "性别",
				staffExcelBean.getGenderId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "民族",
				staffExcelBean.getNationId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "政治面貌",
				staffExcelBean.getPoliticCountenanceId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "国籍",
				staffExcelBean.getNationalityId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "婚姻状态",
				staffExcelBean.getNationalityId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "最高学历",
				staffExcelBean.getEducationalId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "最高学位",
				staffExcelBean.getDegreeId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "管理类别",
				staffExcelBean.getManagementCategoryId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "编制类型",
				staffExcelBean.getCompilationTypeId(), index).getMsg());
//			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "人员类型",
//				staffExcelBean.getStaffTypeId(), index).getMsg());
//			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "人员类别",
//				staffExcelBean.getStaffCategoryId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "职务类别",
				staffExcelBean.getJobCategoryId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "职级",
				staffExcelBean.getRankId(), index).getMsg());
//			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "职等",
//				staffExcelBean.getGradePositionsId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "异动事件",
				staffExcelBean.getChangeEventsId(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "异动类型",
				staffExcelBean.getChangeTypeId(), index).getMsg());

			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE, "2", "出生日期",
				staffExcelBean.getBirthday(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "参加工作时间",
				staffExcelBean.getWorkTime(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "本单位入职时间",
				staffExcelBean.getCompanyInitiationTime(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "异动时间",
				staffExcelBean.getChangeTime(), index).getMsg());
//			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "参加组织时间",
//				staffExcelBean.getParticipationTime(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "排序号",
					staffExcelBean.getOrderNumber(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "入党/团时间",
					staffExcelBean.getJoinPartyTime(), index).getMsg());
			msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "2", "任现职时间",
					staffExcelBean.getTenureTime(), index).getMsg());
		}
		//判断完数据类型若有错直接返回
		if (msg.toString().length() > 0) {
			return new ImportResult(false, msg.toString());
		}
		//判重、先判断输入的编码是否有效(覆盖时需保证导入编码系统已存在，新增时需保证导入编码系统内不存在)

		//自身重复检查
		List<String> repeatList = ImportExcelUtil.findRepeat(codeList);
		for (String value : repeatList) {
			ArrayList<Integer> intList = new ArrayList();
			for (int i = 0; i < codeList.size(); ++i) {
				if (codeList.get(i) != null && codeList.get(i).equals(value)) {
					intList.add(i + 2);
				}
			}
			msg.append(ImportExcelUtil.msgBuilder("2", intList.toString(), "人员编码", value, "重复!"));
		}
		//系统现有编码检查
		Map<String,String> staffFileDataMap = staffFilesList.parallelStream().collect(Collectors.toMap(staffFiles -> EncryptUtil.decryptBase64(staffFiles.getStaffCode(), BASE64_KEY), StaffFiles::getStaffName,(v1, v2)->v1));
		if(isCover) {
			//覆盖时若对应编码不存在，则报错
//			for(int i =0;i<codeList.size();i++) {
//				if (!staffFileDataMap.containsKey(codeList.get(i))) {
//					msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(i+2),"人员编码",codeList.get(i),"不存在"));
//				}
//			}
		}else {
			//新增时若对应编码已存在，则报错
			for(int i =0;i<codeList.size();i++) {
				if (staffFileDataMap.containsKey(codeList.get(i))) {
					msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(i+2),"人员编码",codeList.get(i),"已存在"));
				}
			}
		}

		// 工作流状态检查
		Map<String,Integer> flowMap = staffFilesList.parallelStream()
				.collect(Collectors.toMap(staffFiles -> EncryptUtil.decryptBase64(staffFiles.getStaffCode()
						, BASE64_KEY), StaffFiles::getStatus,(v1, v2)->v1));
		for(int i =0;i<codeList.size();i++) {
			if(flowMap.containsKey(codeList.get(i))){
				if(flowMap.get(codeList.get(i)) == FormStatusConstant.FINISH){
					msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(i+2),"人员编码",codeList.get(i),"已审批通过，无法导入"));
				}else if(flowMap.get(codeList.get(i)) == FormStatusConstant.FLOW){
					msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(i+2),"人员编码",codeList.get(i),"审核中，无法导入"));
				}
			}
		}

		//对象和字典是否存在校验
		int size=readExcels.size();
		int count=0;

		// 单位id加证件号
		List<String> keyList = new ArrayList<>();
		List<String> oldKeyList = new ArrayList<>();
		for (StaffFiles staffFiles : staffFilesList){
			oldKeyList.add(staffFiles.getCompanyNameId() + "-" + staffFiles.getDocumentNumber());
		}
		for(Object readExcel : readExcels){
			StaffFilesExcelBean staffExcelBean =(StaffFilesExcelBean)readExcel;
			int index = readExcels.indexOf(readExcel);
			//职务名称
//			if(StringUtils.isNotEmpty(staffExcelBean.getJobNameId()) && !codeMap.get("jobNameRef").contains(staffExcelBean.getJobNameId())){
//				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"职务名称", staffExcelBean.getJobNameId(), OBJECT_MSG));
//			}
			//证件类型
			if(StringUtils.isNotEmpty(staffExcelBean.getDocumentTypeId()) && !codeMap.get("documentTypeRef").contains(staffExcelBean.getDocumentTypeId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"证件类型", staffExcelBean.getDocumentTypeId(), OBJECT_MSG));
			}
			//性别
			if(StringUtils.isNotEmpty(staffExcelBean.getGenderId()) && !codeMap.get("genderRef").contains(staffExcelBean.getGenderId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"性别", staffExcelBean.getGenderId(), OBJECT_MSG));
			}
			//民族
			if(StringUtils.isNotEmpty(staffExcelBean.getNationId()) && !codeMap.get("nationRef").contains(staffExcelBean.getNationId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"民族", staffExcelBean.getNationId(), OBJECT_MSG));
			}
			//政治面貌
			if(StringUtils.isNotEmpty(staffExcelBean.getPoliticCountenanceId()) && !codeMap.get("politicCountenanceRef").contains(staffExcelBean.getPoliticCountenanceId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"政治面貌", staffExcelBean.getPoliticCountenanceId(), OBJECT_MSG));
			}
			//国籍
			if(StringUtils.isNotEmpty(staffExcelBean.getNationalityId()) && !codeMap.get("nationalityRef").contains(staffExcelBean.getNationalityId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"国籍", staffExcelBean.getNationalityId(), OBJECT_MSG));
			}
			//婚姻状态
			if(StringUtils.isNotEmpty(staffExcelBean.getMaritalStatusId()) && !codeMap.get("maritalStatusRef").contains(staffExcelBean.getMaritalStatusId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"婚姻状态", staffExcelBean.getMaritalStatusId(), OBJECT_MSG));
			}
			//最高学历
			if(StringUtils.isNotEmpty(staffExcelBean.getEducationalId()) && !codeMap.get("educationalRef").contains(staffExcelBean.getEducationalId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"最高学历", staffExcelBean.getEducationalId(), OBJECT_MSG));
			}
			//最高学位
			if(StringUtils.isNotEmpty(staffExcelBean.getDegreeId()) && !codeMap.get("degreeRef").contains(staffExcelBean.getDegreeId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"最高学位", staffExcelBean.getDegreeId(), OBJECT_MSG));
			}
			//管理类别
			if(StringUtils.isNotEmpty(staffExcelBean.getManagementCategoryId()) && !codeMap.get("managementCategoryRef").contains(staffExcelBean.getManagementCategoryId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"管理类别", staffExcelBean.getManagementCategoryId(), OBJECT_MSG));
			}
			//编制类型
			if(StringUtils.isNotEmpty(staffExcelBean.getCompilationTypeId()) && !codeMap.get("compilationTypeRef").contains(staffExcelBean.getCompilationTypeId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"编制类型", staffExcelBean.getCompilationTypeId(), OBJECT_MSG));
			}
			//人员类型
//			if(StringUtils.isNotEmpty(staffExcelBean.getStaffTypeId()) && !codeMap.get("staffTypeRef").contains(staffExcelBean.getStaffTypeId())){
//				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"人员类型", staffExcelBean.getStaffTypeId(), OBJECT_MSG));
//			}
//			//人员类型
//			if(StringUtils.isNotEmpty(staffExcelBean.getStaffCategoryId()) && !codeMap.get("staffCategoryRef").contains(staffExcelBean.getStaffCategoryId())){
//				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"人员类别", staffExcelBean.getStaffCategoryId(), OBJECT_MSG));
//			}
			//职务类别
			if(StringUtils.isNotEmpty(staffExcelBean.getJobCategoryId()) && !codeMap.get("jobCategoryRef").contains(staffExcelBean.getJobCategoryId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"职务类别", staffExcelBean.getJobCategoryId(), OBJECT_MSG));
			}
			//职级
			if(StringUtils.isNotEmpty(staffExcelBean.getRankId()) && !codeMap.get("rankRef").contains(staffExcelBean.getRankId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"职级", staffExcelBean.getRankId(), OBJECT_MSG));
			}
			//职等
//			if(StringUtils.isNotEmpty(staffExcelBean.getGradePositionsId()) && !codeMap.get("gradePositionsRef").contains(staffExcelBean.getGradePositionsId())){
//				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"职等", staffExcelBean.getGradePositionsId(), OBJECT_MSG));
//			}
			//异动事件
			if(StringUtils.isNotEmpty(staffExcelBean.getChangeEventsId()) && !codeMap.get("changeEventsRef").contains(staffExcelBean.getChangeEventsId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"异动事件", staffExcelBean.getChangeEventsId(), OBJECT_MSG));
			}
			//异动类型
			if(StringUtils.isNotEmpty(staffExcelBean.getChangeTypeId()) && !codeMap.get("changeTypeRef").contains(staffExcelBean.getChangeTypeId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"异动类型", staffExcelBean.getChangeTypeId(), OBJECT_MSG));
			}
			//健康状态
			if(StringUtils.isNotEmpty(staffExcelBean.getHealthConditionId()) && !codeMap.get("healthConditionRef").contains(staffExcelBean.getHealthConditionId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"健康状态", staffExcelBean.getHealthConditionId(), OBJECT_MSG));
			}


			//单位名称
			staffExcelBean.setCompanyNameId(StringUtil.cleanChars(staffExcelBean.getCompanyNameId()));
			if(nameMap.get("unitRef").containsKey(staffExcelBean.getCompanyNameId())){
				String companyName = staffExcelBean.getCompanyNameId();
				staffExcelBean.setCompanyNameId(nameMap.get("unitRef").get(staffExcelBean.getCompanyNameId()));
				if (!TokenUtil.getTokenOrgId().equals(staffExcelBean.getCompanyNameId())){
					msg.append(ImportExcelUtil.msgBuilder("2", String.valueOf(index + 2), "单位名称", companyName, "不是当前登录单位"));
				}

			}else if(StringUtils.isNotEmpty(staffExcelBean.getCompanyNameId())){
				msg.append(ImportExcelUtil.msgBuilder("2",String.valueOf(index + 2),"单位名称", staffExcelBean.getCompanyNameId(), OBJECT_MSG));
			}
			// 部门名称 由于部门名称与单位关联，因此当单位名称错误时，会导致部门的校验出错，故需确保单位无误后才可对部门进行校验
			if(msg.length()==0) {
				if (StringUtils.isNotEmpty(staffExcelBean.getCompanyNameId())) {
					if (deptUnitMap.containsKey(staffExcelBean.getCompanyNameId())) {
						if (deptUnitMap.get(staffExcelBean.getCompanyNameId()).containsKey(staffExcelBean.getDepartmentNameId())) {
							staffExcelBean.setDepartmentCode(deptUnitCodeMap.get(staffExcelBean.getCompanyNameId()).get(staffExcelBean.getDepartmentNameId()));
							staffExcelBean.setDepartmentNameId(deptUnitMap.get(staffExcelBean.getCompanyNameId()).get(staffExcelBean.getDepartmentNameId()).toString());
						} else if (StringUtils.isNotEmpty(staffExcelBean.getDepartmentNameId())) {
							msg.append(ImportExcelUtil.msgBuilder("2", String.valueOf(index + 2), "部门名称", staffExcelBean.getDepartmentNameId(), OBJECT_MSG));
						}
					}
					//else 单位不存在
				}
			}

//			if (CollectionUtil.isNotEmpty(keyList) && keyList.contains(staffExcelBean.getCompanyNameId()  + "-" +  staffExcelBean.getDocumentNumber())){
//				msg.append(ImportExcelUtil.msgBuilder("2", String.valueOf(index + 2), "证件号", staffExcelBean.getDocumentNumber(), "重复"));
//			}else {
//				keyList.add(staffExcelBean.getCompanyNameId()  + "-" +  staffExcelBean.getDocumentNumber());
//			}

//			if (CollectionUtil.isNotEmpty(oldKeyList) && oldKeyList.contains(staffExcelBean.getCompanyNameId()  + "-" +  staffExcelBean.getDocumentNumber())){
//				msg.append(ImportExcelUtil.msgBuilder("2", String.valueOf(index + 2), "证件号", staffExcelBean.getDocumentNumber(), "在该单位下已存在"));
//			}


			count++;
			int value = count * 100 / size;
			CacheUtil.put("progress","progress",progressId, value);
			log.info("校验进度："+value);
		}
		//...
		//统一放置报错
		if (msg.toString().length()>0) {
			return new ImportResult(false, msg.toString());
		}
		if (msg.toString().length()>0) {
			return new ImportResult(false, msg.toString());
		}
		return importResult;
	}


}
